package org.jeecg.modules.weixin.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.modules.demo.allvipcard.entity.AllVipcard;
import org.jeecg.modules.demo.allvipcard.service.IAllVipcardService;
import org.jeecg.modules.demo.basemembertoreceivevip.entity.BaseMemberToReceiveVip;
import org.jeecg.modules.demo.basemembertoreceivevip.service.IBaseMemberToReceiveVipService;
import org.jeecg.modules.demo.basemembertoreceivevipcoupon.entity.BaseMemberToReceiveVipCoupon;
import org.jeecg.modules.demo.basemembertoreceivevipcoupon.service.IBaseMemberToReceiveVipCouponService;
import org.jeecg.modules.demo.couponmanagement.entity.CouponManagement;
import org.jeecg.modules.demo.levelset.entity.LevelSet;
import org.jeecg.modules.demo.levelset.service.ILevelSetService;
import org.jeecg.modules.demo.membermanagement.entity.MemberManagement;
import org.jeecg.modules.demo.membermanagement.service.IMemberManagementService;
import org.jeecg.modules.demo.msgtemplatelist.entity.MsgTemplate;
import org.jeecg.modules.demo.msgtemplatelist.service.IMsgTemplateService;
import org.jeecg.modules.demo.storeinfo.entity.StoreInfo;
import org.jeecg.modules.demo.storeinfo.service.IStoreInfoService;
import org.jeecg.modules.demo.vipcarddrawrecord.entity.VipcardDrawRecord;
import org.jeecg.modules.demo.vipcarddrawrecord.service.IVipcardDrawRecordService;
import org.jeecg.modules.demo.widthmanagement.entity.WidthManagement;
import org.jeecg.modules.demo.widthmanagement.service.IWidthManagementService;
import org.jeecg.modules.util.HttpUtils;
import org.jeecg.modules.util.JaxbXmlUtil;
import org.jeecg.modules.util.SHA1Utils;
import org.jeecg.modules.wechat.result.xcx.ApiOpenCreateReturn;
import org.jeecg.modules.wechat.result.xcx.OpenCreateAppid;
import org.jeecg.modules.wechat.service.WechatThirdMiniProgramService;
import org.jeecg.modules.weixin.entity.WechatEventMessage;
import org.jeecg.modules.weixin.util;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.xml.bind.JAXBException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

@RestController
@RequestMapping("/wechat")
@Slf4j
public class WechatController {

    @Autowired
    private IStoreInfoService storeInfoService;
    @Autowired
    private IMemberManagementService memberManagementService;
    @Autowired
    private ILevelSetService levelSetService;
    @Autowired
    private IAllVipcardService allVipcardService;
    @Autowired
    private IBaseMemberToReceiveVipService baseMemberToReceiveVipService;
    @Autowired
    private IBaseMemberToReceiveVipCouponService baseMemberToReceiveVipCouponService;
    @Autowired
    private IVipcardDrawRecordService vipcardDrawRecordService;
    @Autowired
    private IMsgTemplateService msgTemplateListService;
    @Autowired
    private WechatThirdMiniProgramService wechatThirdMiniProgramService;

    @GetMapping(value = "/url/{storeName}")
    public String queryPageList(@PathVariable("storeName") String storeName
            , @RequestParam("signature") String signature, @RequestParam("timestamp") String timestamp, @RequestParam("nonce") String nonce, @RequestParam("echostr") String echostr){

        log.info("微信公众号GET调用，storeName = {}, signature = {}, timestamp = {}, nonce = {}, echostr = {}", storeName, signature, timestamp, nonce, echostr);

        try {
            if (StringUtils.isEmpty(signature) || StringUtils.isEmpty(timestamp) || StringUtils.isEmpty(nonce) || StringUtils.isEmpty(echostr)) {
                log.info("微信公众号GET调用，参数不全，返回false");
                return "false";
            }
            List<StoreInfo> storeList = storeInfoService.list(new QueryWrapper<StoreInfo>().eq("gzh_store_name", storeName));
            if (storeList.size() == 0) {
                log.info("微信公众号GET调用，未匹配到店铺，返回false");
                return "false";
            }
            if (storeList.size() > 1) {
                log.info("微信公众号GET调用，店铺数量大于1个，返回false");
                return "false";
            }
            StoreInfo store = storeList.get(0);
            if (StringUtils.isEmpty(store.getGzhToken())) {
                log.info("微信公众号GET调用，店铺未填写token，返回false");
                return "false";
            }
            //String token = "kyz66";

            String[] paramArray = new String[]{store.getGzhToken(), timestamp, nonce};
            Arrays.sort(paramArray);
            StringBuilder params = new StringBuilder();
            for (String str : paramArray) {
                params.append(str);
            }
            if (signature.equals(SHA1Utils.encode(params.toString()))) {
                log.info("微信公众号GET调用，返回true");
                //return "true";
                return  echostr;
            }
            log.info("微信公众号GET调用，签名对比失败，返回false");
            return "false";
        } catch (Exception e) {
            log.error("微信公众号GET调用，发生异常，返回false", e);
            return "false";
        }
    }

    @PostMapping(value = "/url/{storeName}")
    public String queryPageList(@PathVariable("storeName") String storeName, @RequestBody() String body) {

        log.info("微信公众号POST调用，storeName = {}, body = {}", storeName, body);

        try {
            List<StoreInfo> storeList = storeInfoService.list(new QueryWrapper<StoreInfo>().eq("gzh_store_name", storeName));
            if (storeList.size() == 0) {
                log.info("微信公众号POST调用，未匹配到店铺，返回空");
                return "";
            }
            if (storeList.size() > 1) {
                log.info("微信公众号POST调用，店铺数量大于1个，返回空");
                return "";
            }
            StoreInfo store = storeList.get(0);
            String storeId = store.getId();
            String gzhAppId = store.getGzhAppId();
            String gzhAppSecret = store.getGzhAppSecret();
            if (StringUtils.isEmpty(store.getGzhAppId()) || StringUtils.isEmpty(store.getGzhAppSecret())) {
                log.info("微信公众号POST调用，店铺未绑定公众号，返回空");
                return "";
            }
            if (StringUtils.isEmpty(store.getXcxAppId())) {
                log.info("微信公众号POST调用，店铺未绑定小程序，返回空");
                return "";
            }
            WechatEventMessage event = null;
            try {
                event = JaxbXmlUtil.convertToJavaBean(body, WechatEventMessage.class);
            } catch (JAXBException e) {
                log.error("XML解析失败，向微信服务器返回空字符串", e);
                return "";
            }
            // 关注事件
            if ("event".equals(event.getMsgType()) && "subscribe".equals(event.getEvent())) {
                String openid = event.getFromUserName();

                String url1 = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + gzhAppId + "&secret=" + gzhAppSecret;
                String result1 = HttpUtils.sendGet(url1);
                JSONObject resultJson1 = JSON.parseObject(result1);
                String errcode = resultJson1.getString("errcode");
                if (errcode != null && !"0".equals(errcode)) {
                    log.debug("微信公众号POST调用，获取accessToken返回值异常，错误码：{}", errcode);
                    return "";
                }
                String accessToken = resultJson1.getString("access_token");

                String url2 = "https://api.weixin.qq.com/cgi-bin/user/info?access_token=" + accessToken + "&openid=" + openid + "&lang=zh_CN";
                String result2 = HttpUtils.sendGet(url2);
                log.debug("微信调用：url = {}, result = {}", url2, result2);
                JSONObject resultJson2 = JSON.parseObject(result2);
                String errcode2 = resultJson2.getString("errcode");
                if (errcode2 != null && !"0".equals(errcode2)) {
                    log.debug("微信公众号POST调用，调用微信api返回值异常，错误码：{}", errcode2);
                    return "";
                }

                String unionId = resultJson2.getString("unionid");

                //MemberManagement mm = memberManagementService.getOne(new QueryWrapper<MemberManagement>().eq("store_id", storeId).eq("gzh_open_id", openid));
                MemberManagement mm = memberManagementService.getOneRecordByUnionId(storeId,unionId);
                if (mm != null) {
                    log.info("关注事件 mm is not null");
                    log.info("关注事件 开始update...");
                    mm.setUpdateBy("gzh");
                    mm.setGzhOpenId(openid);
                    mm.setWhetherConcern("1");
                    memberManagementService.updateById(mm);
                    log.info("关注事件 结束update...");
                } else {
                    log.info("关注事件 mm is null");
                    MemberManagement mm1 = new MemberManagement();
                    mm1.setStoreId(storeId);
                    mm1.setGzhOpenId(openid);
                    mm1.setUnionId(unionId);
                    mm1.setUserinfoStatus("0");
                    mm1.setConsumption(0);
                    mm1.setAmount(0.00);
                    mm1.setBalance(0.00);
                    mm1.setExpendamount(0.00);
                    mm1.setShareholderDividends(0.00);
                    mm1.setStockMemberExpendamount(0.00);
                    mm1.setRegistrationDate(new Date());
                    mm1.setWhetherConcern("1");
                    mm1.setIsNew("1");
                    mm1.setStatus("2");
                    mm1.setMemberType("店铺会员");
                    List<LevelSet> levelSetList = levelSetService.list(new QueryWrapper<LevelSet>().eq("store_id", storeId).orderByAsc("rank_num"));
                    if (levelSetList == null || levelSetList.size() == 0) {
                        log.debug("微信公众号POST调用，店铺还未创建会员等级");
                        return "";
                    }
                    mm1.setLevelId(levelSetList.get(0).getId());
                    mm1.setShareholders(null);
                    mm1.setBelongStore(null);
                    mm1.setMemberLevel(null);
                    mm1.setCreateBy("gzh");
                    mm1.setUserinfoStatus("0");
                    log.info("start save member.....");
                    memberManagementService.save(mm1);
                    log.info("end save member.....");
                    // 首次关注发放新人卡
                    AllVipcard av = allVipcardService.getOne(new QueryWrapper<AllVipcard>().eq("store_id", storeId).eq("card_type", "新人卡"));
                    if (av != null) {
                        // 贵宾卡关联的优惠劵，数量已从关联表中带出
                        List<CouponManagement> cmList = allVipcardService.listCouponsByVipId(av.getId(), storeId);
                        // 待领取表增加数据
                        BaseMemberToReceiveVip toReceiveVip = new BaseMemberToReceiveVip();
                        BeanUtils.copyProperties(av, toReceiveVip);
                        toReceiveVip.setId(null);
                        toReceiveVip.setCreateTime(null);
                        toReceiveVip.setCreateBy(null);
                        toReceiveVip.setUpdateTime(null);
                        toReceiveVip.setUpdateBy(null);
                        toReceiveVip.setType("1");
                        toReceiveVip.setMemberId(mm1.getId());
                        toReceiveVip.setStatus("0");
                        toReceiveVip.setShareNum(0);
                        baseMemberToReceiveVipService.save(toReceiveVip);

                        VipcardDrawRecord vipcardDrawRecord = new VipcardDrawRecord();
                        vipcardDrawRecord.setCreateBy("xcx");
                        vipcardDrawRecord.setCreateTime(new Date());
                        vipcardDrawRecord.setMemberId(mm1.getId());
                        vipcardDrawRecord.setStoreId(av.getStoreId());
                        vipcardDrawRecord.setVipId(av.getId());
                        vipcardDrawRecord.setDrawDate(new Date());
                        vipcardDrawRecord.setIssuingRecordsId(toReceiveVip.getIssuingRecordsId());
                        vipcardDrawRecord.setRemark("queryPageList");
                        vipcardDrawRecordService.save(vipcardDrawRecord);
                        for (CouponManagement coupon : cmList) {
                            BaseMemberToReceiveVipCoupon toReceiveVipCoupon = new BaseMemberToReceiveVipCoupon();
                            BeanUtils.copyProperties(coupon, toReceiveVipCoupon);
                            toReceiveVipCoupon.setId(null);
                            toReceiveVipCoupon.setCreateTime(null);
                            toReceiveVipCoupon.setCreateBy(null);
                            toReceiveVipCoupon.setUpdateTime(null);
                            toReceiveVipCoupon.setUpdateBy(null);
                            toReceiveVipCoupon.setToReceiveVipId(toReceiveVip.getId());
                            toReceiveVipCoupon.setMemberId(mm1.getId());
                            toReceiveVipCoupon.setNum(Integer.parseInt(coupon.getNum()));
                            baseMemberToReceiveVipCouponService.save(toReceiveVipCoupon);
                        }
                        SimpleDateFormat sdf = new SimpleDateFormat("yyyy年M月d日 HH:mm");
                        MsgTemplate msgTemplate = msgTemplateListService.getByTitle("规划任务生成提醒",storeId);
                        String templateId = msgTemplate.getTemplateId();
                        log.info("templateId:"+templateId);
                        util.unclaimedCardNotice(templateId,openid, "新人卡", sdf.format(new Date()), store.getXcxAppId(), "shop/guest/info?vipId=" + toReceiveVip.getId() + "&type=3", accessToken);
                    }
                }
            }

            // 取消关注事件
            if ("event".equals(event.getMsgType()) && "unsubscribe".equals(event.getEvent())) {
                String openid = event.getFromUserName();

                String url1 = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + gzhAppId + "&secret=" + gzhAppSecret;
                String result1 = HttpUtils.sendGet(url1);
                JSONObject resultJson1 = JSON.parseObject(result1);
                String errcode = resultJson1.getString("errcode");
                if (errcode != null && !"0".equals(errcode)) {
                    log.debug("微信公众号POST调用，获取accessToken返回值异常，错误码：{}", errcode);
                    return "";
                }
                String accessToken = resultJson1.getString("access_token");

                String url2 = "https://api.weixin.qq.com/cgi-bin/user/info?access_token=" + accessToken + "&openid=" + openid + "&lang=zh_CN";
                String result2 = HttpUtils.sendGet(url2);
                log.debug("微信调用：url = {}, result = {}", url2, result2);
                JSONObject resultJson2 = JSON.parseObject(result2);
                String errcode2 = resultJson2.getString("errcode");
                if (errcode2 != null && !"0".equals(errcode2)) {
                    log.debug("微信公众号POST调用，调用微信api返回值异常，错误码：{}", errcode2);
                    return "";
                }
                // 取关的时候取不到unionId
//                String unionId = resultJson2.getString("unionid");
                String gzhOpenId = resultJson2.getString("openid");

                MemberManagement mm = memberManagementService.getOne(new QueryWrapper<MemberManagement>().eq("store_id", storeId).eq("gzh_open_id", gzhOpenId));
                if (mm != null) {
                    mm.setUpdateBy("gzh");
                    mm.setWhetherConcern("0");
                    memberManagementService.updateById(mm);
                }
            }

            return "";
        } catch (Exception e) {
            log.error("微信公众号POST调用，发生异常，返回空", e);
            return "";
        }
    }
}
